package com.ruoyi.yljf.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.yljf.domain.CommentLike;
import com.ruoyi.yljf.domain.User;
import com.ruoyi.yljf.domain.dto.CommentAddDTO;
import com.ruoyi.yljf.domain.dto.CommentDTO;
import com.ruoyi.yljf.domain.vo.CommentReplyListVO;
import com.ruoyi.yljf.domain.vo.CourseCommentVO;
import com.ruoyi.yljf.domain.vo.RedMoreVO;
import com.ruoyi.yljf.mapper.CommentLikeMapper;
import com.ruoyi.yljf.service.IUserService;
import com.ruoyi.yljf.util.CommonUtils;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.yljf.mapper.CommentMapper;
import com.ruoyi.yljf.domain.Comment;
import com.ruoyi.yljf.service.ICommentService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 评论管理Service业务层处理
 * 
 * @author metaee
 * @date 2025-02-14
 */
@Service
@AllArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService {

	@Resource
    private final CommentMapper commentMapper;
    
	@Resource
	private IUserService userService;
	
    @Autowired
    private TokenService tokenService;
//
    @Autowired
    private CommonUtils commonUtils;

	@Resource
	private CommentLikeMapper commentLikeMapper;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
    
    /**
     * 查询评论管理列表
     * 
     * @param comment 评论管理
     * @return 评论管理
     */
    @Override
    public List<Comment> selectCommentList(Comment comment) {
    	LambdaQueryWrapper<Comment> queryWrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotEmpty(comment.getContent())) {
			queryWrapper.eq(Comment::getContent, comment.getContent());
		}
        if (StringUtils.isNotNull(comment.getUserId())) {
			queryWrapper.eq(Comment::getUserId, comment.getUserId());
		}
        if (StringUtils.isNotNull(comment.getToUserId())) {
			queryWrapper.eq(Comment::getToUserId, comment.getToUserId());
		}
        if (StringUtils.isNotEmpty(comment.getUserName())) {
			queryWrapper.like(Comment::getUserName, comment.getUserName());
		}
        if (StringUtils.isNotNull(comment.getPostId())) {
			queryWrapper.eq(Comment::getPostId, comment.getPostId());
		}
        if (StringUtils.isNotEmpty(comment.getPostType())) {
			queryWrapper.eq(Comment::getPostType, comment.getPostType());
		}
        if (StringUtils.isNotNull(comment.getParentId())) {
			queryWrapper.eq(Comment::getParentId, comment.getParentId());
		}
        if (StringUtils.isNotEmpty(comment.getIsRead())) {
			queryWrapper.eq(Comment::getIsRead, comment.getIsRead());
		}
        return commentMapper.selectList(queryWrapper);
    }


	/**
	 *
	 * @param list 子评论
	 * @return
	 */
	@Override
	public List<CommentReplyListVO> replyList(List<Comment> list) {
		//1.查询所有我的评论
		LoginUser loginUser = SecurityUtils.getLoginUser();
		Long userId = loginUser.getUserId();
		List<Comment> comments = commentMapper.selectList(new LambdaQueryWrapper<>(Comment.class)
				.eq(Comment::getUserId, userId).ne(Comment::getPostType,"question").orderByDesc(Comment::getCreateTime));
		//收集所有我的评论id
		List<Long> myCommentIds = comments.stream().map(Comment::getId).collect(Collectors.toList());
		
//		//2.查询我的所有子评论
//		List<Comment> sonComments = commentMapper.selectList(new QueryWrapper<Comment>().in("parent_id",myCommentIds));
		//收集所有我的子评论id
//		List<Long> sonCommentIds = sonComments.stream().map(Comment::getId).collect(Collectors.toList());
		//所有关于我的评论信息
//		ArrayList<Long> allCommentIds = new ArrayList<>();
//		allCommentIds.addAll(myCommentIds);
//		allCommentIds.addAll(sonCommentIds);
//		List<Comment> allCommentList = commentMapper.selectList(new QueryWrapper<Comment>().in("id", allCommentIds));
		comments.addAll(list);
		List<Comment> allCommentList = comments.stream().distinct().collect(Collectors.toList());
		//2.1封装成map
		Map<Long, Comment> allCommentMap = comments.stream().collect(Collectors.toMap(Comment::getId, item -> item));

		
		ArrayList<CommentReplyListVO> result = new ArrayList<>();
		//进行封装
		for (Comment sonComment : list) {

			CommentReplyListVO commentReplyListVO = new CommentReplyListVO();

			commentReplyListVO.setReplyId(sonComment.getId());
			commentReplyListVO.setAvatar(sonComment.getUserAvatar());
			commentReplyListVO.setUserName(sonComment.getUserName());
			commentReplyListVO.setReplyTime(sonComment.getCreateTime());
			commentReplyListVO.setContent(sonComment.getContent());
			commentReplyListVO.setIsRead(sonComment.getIsRead());

			//封装接收人昵称，接收人姓名
			Long toCommentId = sonComment.getToCommentId();
			Comment comment = allCommentMap.get(toCommentId);
			commentReplyListVO.setToUserName(comment.getUserName());
			commentReplyListVO.setRepliedContent(comment.getContent());

			result.add(commentReplyListVO);

		}

		return result;
	}

	
	@Override
	public Integer commentAdd(CommentAddDTO request) {

		Comment comment = new Comment();
		BeanUtils.copyProperties(request,comment);
		
		//封装当前登录用户id、姓名、头像
		LoginUser loginUser = SecurityUtils.getLoginUser();
		Long userId = loginUser.getUserId();
		comment.setUserId(userId);

		User user = userService.getById(userId);
		if (user != null){
			comment.setUserName(user.getUserName());
			comment.setUserAvatar(user.getAvatar());
		}
		
		//parentId为null说明走的新增
		if (request.getParentId() == null){
			comment.setParentId(0L);
			comment.setIsRead("Y");
		}

		return commentMapper.insert(comment);

	}

	@Override
	public List<CommentReplyListVO> queryAsk(List<Comment> list) {
		//查询我的所有提问,提问绑定courseId
		List<Comment> questionList = commentMapper.selectList(
				//封装查询参数
				new LambdaQueryWrapper<>(Comment.class)
						.eq(Comment::getPostType, "question")
						.eq(Comment::getUserId, SecurityUtils.getUserId())
						.orderByDesc(Comment::getCreateTime)

		);
		ArrayList<CommentReplyListVO> result = new ArrayList<>();

		if (ObjectUtils.isNotNull(questionList)) {
			//收集所有我的提问id
//			List<Long> myCommentIds = questionList.stream().map(Comment::getId).collect(Collectors.toList());
			//查询我所有提问的回复
//			List<Comment> sonComments = commentMapper.selectList(new QueryWrapper<Comment>().in("parent_id",myCommentIds));
//		//收集所有我的提问的回复id
//		List<Long> sonCommentIds = sonComments.stream().map(Comment::getId).collect(Collectors.toList());
			questionList.addAll(list);
			List<Comment> collect1 = questionList.stream().distinct().collect(Collectors.toList());

			//2.1封装成map
			Map<Long, Comment> allCommentMap = collect1.stream().collect(Collectors.toMap(Comment::getId, item -> item));
			//进行封装
			for (Comment sonComment : list) {

				CommentReplyListVO commentReplyListVO = new CommentReplyListVO();

				commentReplyListVO.setReplyId(sonComment.getId());
				commentReplyListVO.setAvatar(sonComment.getUserAvatar());
				commentReplyListVO.setUserName(sonComment.getUserName());
				commentReplyListVO.setReplyTime(sonComment.getCreateTime());
				commentReplyListVO.setContent(sonComment.getContent());
				commentReplyListVO.setIsRead(sonComment.getIsRead());

				//封装接收人昵称，接收人姓名
				Long toCommentId = sonComment.getToCommentId();
				Comment comment = allCommentMap.get(toCommentId);
				commentReplyListVO.setToUserName(comment.getUserName());
				commentReplyListVO.setRepliedContent(comment.getContent());

				result.add(commentReplyListVO);

			}

		}
		return result;
	}

	@Override
	public List<Comment> queryList(CommentDTO dto) {
		return commentMapper.selectList(
				new LambdaQueryWrapper<>(Comment.class)
						.eq(Comment::getPostType, dto.getType())
						.eq(Comment::getPostId, dto.getId())
						.eq(Comment::getParentId,0)
						.orderByDesc("hot".equals(dto.getOrder()), Comment::getLikes)
						.orderByDesc("time".equals(dto.getOrder()), Comment::getCreateTime)
		);
	}

	@Override
	public List<CourseCommentVO> courseReplyList(List<Comment> list, HttpServletRequest request) {

		//查询子评论数量 ，最终返回一级评论和子评论数量
		List<CourseCommentVO> collect = list.stream().map(item -> {
			CourseCommentVO courseCommentVO = new CourseCommentVO(item);
			boolean liked = isLiked(item.getId(), SecurityUtils.getUserId());  // 判断当前用户是否对该评论点赞
			courseCommentVO.setIfLike(liked);
			Long l = commentMapper.selectCount(
					new LambdaQueryWrapper<>(Comment.class)
							.eq(Comment::getParentId, item.getId())
			);
			courseCommentVO.setChildNum(l);
			return courseCommentVO;
		}).collect(Collectors.toList());

		if (commonUtils.userIfLogin(request)){
			//TODO 用户登录的话,需要去查询点赞记录是否有点赞，有的话修改collect的对应字段为已点赞


		}

		return collect;
	}

	@Override
	public List<Comment> selectByParentId(Long commentId) {
//		Comment comment = commentMapper.selectOne(new LambdaQueryWrapper<>(Comment.class)
//				.eq(Comment::getId, commentId));

		LambdaQueryWrapper<Comment> wapper = new LambdaQueryWrapper<>(Comment.class);
		wapper.eq(Comment::getParentId, commentId)
				.or()
				.eq(Comment::getId, commentId);
//						.orderByDesc(Comment::getCreateTime)
		if (commentId == 0) {
			wapper.orderByDesc(Comment::getCreateTime);
		}

		return commentMapper.selectList(wapper);
	}


	@Override
	public List<RedMoreVO> readMore(List<Comment> list) {

		List<RedMoreVO> collect = new ArrayList<>();
		if (ObjectUtils.isNotNull(list)) {
				 collect = list.stream().map(item -> {
					 RedMoreVO redMoreVO = new RedMoreVO(item);
					 boolean liked = isLiked(item.getId(), SecurityUtils.getUserId());  // 判断当前用户是否对该评论点赞
					 redMoreVO.setIfLike(liked);
					 return redMoreVO;
				 }).collect(Collectors.toList());

			Set<Long> toUserIds = collect.stream()
					.map(RedMoreVO::getToUserId)
					.filter(Objects::nonNull) // 可选：排除null值
					.collect(Collectors.toCollection(LinkedHashSet::new));
			List<User> users = userService.listByIds(toUserIds);
			Map<Long, User> userMap = users.stream()
					.collect(Collectors.toMap(User::getUserId,  user -> user));
			collect.forEach(redMoreVO  -> {
				Long toUserId = redMoreVO.getToUserId();
				User user = userMap.get(toUserId);
				if (userMap.containsKey(toUserId))  {
					redMoreVO.setToUserName(user.getUserName());
					redMoreVO.setToUserAvatar(user.getAvatar());
				}
			});
		}
		return collect;
	}

	@Override
	public AjaxResult like(Long commentId, HttpServletRequest req) {
		Comment comment = commentMapper.selectById(commentId);
		if(comment == null) {
			return AjaxResult.error("评论不存在");
		}
		String commentLikeKey = CacheConstants.COMMENT_LIKED_KEY + commentId;
		Long userId = tokenService.getLoginUser(req).getUserId();
		if(Boolean.TRUE.equals(isLiked(commentId, userId))) { // 用户已经点赞
			stringRedisTemplate.opsForSet().remove(commentLikeKey, String.valueOf(userId));
			commentMapper.unLike(commentId);
			LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(CommentLike::getCommentId, commentId)
					.eq(CommentLike::getUserId, userId);
			commentLikeMapper.delete(wrapper);
			return AjaxResult.success("取消点赞成功");
		} else {  // 评论点赞
			stringRedisTemplate.opsForSet().add(commentLikeKey, String.valueOf(userId));
			commentMapper.like(commentId);
			CommentLike commentLike = new CommentLike();
			commentLike.setUserId(userId);
			commentLike.setCommentId(commentId);
			commentLike.setCreateTime(new Date());
			commentLikeMapper.insert(commentLike);
			return AjaxResult.success("点赞成功");
		}
	}

	@Override
	public List<Comment> selectCount(Long userId, String type) {
		return commentMapper.queryList(userId,type);
	}

	@Override
	public List<Comment> selectQuestionCount(Long userId, String type) {
		return commentMapper.selectQuestionCount(userId,type);
	}

	/**
	 * 判断对评论用户是否点赞
	 * @param commemtId：当前判断评论id
	 * @param userId；当前用户id
	 * @return
	 */
	private boolean isLiked(Long commemtId, Long userId) {
		// 2.判断当前登录用户是否已经点赞
		String key = CacheConstants.COMMENT_LIKED_KEY + commemtId;
		boolean is = Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember(key, userId.toString()));
		if(!is){
			// 查数据库点赞记录
			LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(CommentLike::getUserId, userId)
					.eq(CommentLike::getCommentId, commemtId);
			Long aLong = commentLikeMapper.selectCount(wrapper);
			if(aLong != 0) {  // 数据库中已经点赞了，将点赞在Redis中标记
				stringRedisTemplate.opsForSet().add(key, userId.toString());
			} else {  // 数据库该用户也未点赞，直接返回未点赞
				return false;
			}
		}
		return is;
	}

}
